package com.xiyou.luckdraw.web.config;

import com.xiyou.luckdraw.api.dal.mapper.luckdraw.LoginMapper;
import com.xiyou.luckdraw.api.dto.login.LoginUserInfoResponse;
import com.xiyou.luckdraw.api.dto.login.RolePermission;
import com.xiyou.luckdraw.api.dto.login.UserInfoDto;
import com.xiyou.luckdraw.api.dto.login.UserRoleInfo;
import com.xiyou.luckdraw.api.service.LoginService;
import com.xiyou.luckdraw.common.utils.MD5Utils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.stream.Collectors;

/**
 * @ClassName: CustomRealm
 * @Description:
 * @author: limingxing
 * @Date: 2019-10-08 16:30
 */
@Slf4j
@Component
public class CustomRealm extends AuthorizingRealm {

    @Autowired
    private LoginService loginService;

    /**
     * 获取身份验证信息
     * Shiro中，最终是通过 Realm 来获取应用程序中的用户、角色及权限信息的。
     * @param authenticationToken 用户身份信息 token
     * @return 返回封装了用户信息的 AuthenticationInfo 实例
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        log.info("doGetAuthenticationInfo authenticationToken: {}",authenticationToken.toString());
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        //从数据库获取对应用户名密码的用户
        UserInfoDto user = loginService.getUser(token.getUsername());
        log.info("doGetAuthenticationInfo user: {}",user);
        String loginPassword = MD5Utils.encode(new String(token.getPassword()), token.getUsername());
        if (null == user) {
            throw new AccountException("用户名或密码错误！");
        }
        if (!user.getPassword().equals(loginPassword)) {
            log.info("用户或密码错误");
            throw new AccountException("用户名或密码错误！");
        }
        //
        //处理密码
        token.setPassword(loginPassword.toCharArray());
        LoginUserInfoResponse loginUserInfo = new LoginUserInfoResponse();
        loginUserInfo.setUserInfo(user);
        loginUserInfo.setRoleInfo(loginService.getRole(user.getId()));
        loginUserInfo.setPermissionInfo(loginService.getPermission(user.getId()));
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(loginUserInfo, user.getPassword(), getName());
        return simpleAuthenticationInfo;
    }

    /**
     * 获取授权信息
     *
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        log.info("————权限认证————");
        LoginUserInfoResponse loginUserInfo = (LoginUserInfoResponse) SecurityUtils.getSubject().getPrincipal();
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        if (CollectionUtils.isNotEmpty(loginUserInfo.getRoleInfo())) {
            info.setRoles(loginUserInfo.getRoleInfo().stream().map(UserRoleInfo::getCode).collect(Collectors.toSet()));

        }
        if (CollectionUtils.isNotEmpty(loginUserInfo.getPermissionInfo())) {
            info.setStringPermissions(loginUserInfo.getPermissionInfo().stream().map(RolePermission::getCode).collect(Collectors.toSet()));
        }
        return info;
    }
}
